<template>
  <div class="channel-edit-container">
    <!-- 频道编辑弹框内容 -->
    <van-cell title="我的频道" :border="false">
    <!-- 标题 -->
      <template #title>
        <div>我的频道</div>
      </template>
      <!-- 右侧按钮 -->
      <template #default>
        <van-button
          class="edit-btn"
          plain round type="danger"
          size="mini"
          @click="isEditShow=!isEditShow"
        >
          {{isEditShow ? '完成' : '编辑'}}
        </van-button>
      </template>
    </van-cell>

    <!-- 内容区域 -->
    <van-grid :gutter="10">
      <van-grid-item
        v-for="(item,index) in myChannels"
        :key="index"
        class="channel-item"
        @click="goChannel(item, index)"
        >
        <template #icon>
          <van-icon name="close"  v-show="isEditShow && index !== 0" />
        </template>
        <template #text>
          <span class="text" :class="{active: active === index}">{{item.name}}</span>
        </template>
      </van-grid-item>
    </van-grid>

    <!-- 频道操作 -->
    <van-cell :border="false">
    <!-- 标题 -->
      <template #title>
        <div>频道推荐</div>
      </template>
    </van-cell>

    <!-- 内容区域 -->
    <van-grid :gutter="10" class="recommend-grid">
      <van-grid-item
        v-for="(obj,index) in recommendChannels"
        :key="index"
        icon="plus"
        class="channel-item"
        @click="onAddChannel(obj)"
        >
        <template #text>
          <span class="text">{{obj.name}}</span>
        </template>
      </van-grid-item>
    </van-grid>
  </div>
</template>

<script>
/*
  目标1: 通过首页的频道列表中的数据展示到编辑频道弹出层中
  1. 将父组件中的channels频道列表传递给子组件
  2. 通过props获取数据后遍历到页面上
*/

/*
  目标2: 在编辑遮罩中, 展示首页选中的频道
  1. 将父组件中v-tabs上绑定的当前选中的索引遍历active, 传给遮罩层
  2. 在子组件中设置动态样式, 去区别当前首页显示的频道
  3. 当设置动态class发现, 无法影响ui组件中的某一个小元素样式, 那么想办法将该小元素以插槽的形式显示的提取出来,再设置动态class
*/

/*
  目标3: 获取并展示所有频道接口
  1. 查阅接口文档, 并封装对应的接口, 在index.js输出
  2. 通过分析, 为了最大的保证用户体验, 将获取全部频道的数据方法写在home.vue父组件中
  3. 在父组件中将全部频道数据传递给子组件

  展示:
  1. 通过计算属性 => 推荐频道 - 我的频道 => 得到一个推荐频道的计算属性
  2. 把该计算属性数组遍历到推荐频道的页面上去

  使用lodash方法类库的步骤
  1. npm i lodash
  2. 在main.js中全局引入lodash, 并设置实例方法
  3. 可以通过this.$xxx的形式进行组件的使用
*/

/*
  目标4: 添加频道
  1. 给推荐频道中的每一个小频道绑定点击事件
  2. 通过点击事件将当前的频道元素对象通过push方式添加到我的频道中
*/

/*
  目标5: 编辑频道操作
  1. 切换编辑与跳转状态
    1.1 创建一个状态变量,通过该变量来影响删除图标,编辑/完成按钮的展示
    1.2 给编辑完成按钮绑定点击事件,来实现状态变量的切换
    1.3 我的频道中推荐不可以被删除
  2. 切换频道逻辑
    2.1 给我的频道中的每一个小频道绑定点击事件
    2.2 通过判断状态值isEditSHow的当前模式为false时, 则进行跳转切换操作
    2.3 通过$emit()方式触发父组件的自定义事件来实现active状态的切换
    2.4 主动关闭遮罩层
  3. 删除频道操作逻辑
  现象:
    3.1 在编辑状态下, 点击非推荐的频道,在我的频道中删除, 在频道推荐的列表中显示
    3.2 在首页,同样被删除的频道不显示
    3.3 删除其他非高亮频道时, 不会影响高亮频道的重新选择
    3.4 删除高亮频道时, 会将高亮的频道切换到当前高亮频道的往左数的第一个频道位置
  操作:
    3.1 在频道点击事件的isEditShow为true(编辑状态时), 触发我的频道列表的删除操作(splice)
    3.2 推荐频道列表不需要做添加操作,因为是通过计算属性得到的数组,会自动计算
    3.3 首页的channels频道列表也不需要做删除操作,因为channels和myChannels是共享堆内存中的数据
    3.4 如果删除的哪个元素所在的索引 小于等于 当前高亮频道的索引, 需要将当前高亮索引值(active) - 1
    3.5 当删除某个频道时,编辑弹出层自动关闭了 - 通过新增参数来判断是否关闭
*/

/*
  目标6: 持久化数据 - 描述: 有登录状态,调用接口和获取新增修改查询数据; 无登录状态, 通过本地缓存获取数据
  1. 添加频道时的数据持久化
    1.1 通过用户登录状态(store.state.user.token是否存在)来判断是调用接口还是本地缓存
    1.2 获取token的方式 - 1-this.$store.state.user.token; 2-vuex内置方法mapState

  2. 删除频道时的数据持久化

*/
import { mapState } from 'vuex'
import { setItem } from '../../../utils/storage.js'
import { addUserChannelAPI, delUserChannelAPI } from '../../../api/index.js'
export default {
  name: 'channelEdit',
  props: {
    myChannels: {
      type: Array,
      default: () => []
    },
    active: {
      type: Number,
      default: 0
    },
    allChannels: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      myChannelsClone: this.myChannels,
      isEditShow: false // 控制编辑状态
    }
  },
  computed: {
    ...mapState(['user']),
    // 推荐频道
    recommendChannels () {
      const tempList = this.allChannels.filter(channel => {
        const index = this.myChannels.findIndex(myChannel => {
          return myChannel.id === channel.id
        })
        return index === -1
      })
      return tempList
      // differenceBy可能返回的数据是一个伪数组, 那么建议对返回的数组做一次真数组处理
      // return [...this.$_.differenceBy(this.allChannels, this.myChannels, 'id')]
    }
  },
  methods: {
    // 添加到我的频道
    async onAddChannel (channel) {
      // 不可以直接修改父组件中传递过来的数据, 所以需要在data中拷贝一份,再去修改堆内存中的数据
      this.myChannelsClone.push(channel)

      // 数据持久化, 判断用户是否登录
      if (this.user.token) {
        // 已登录 - 调接口
        try {
          await addUserChannelAPI({
            id: channel.id,
            seq: this.myChannels.length
          })
        } catch (error) {
          console.log(error)
        }
      } else {
        // 未登录 - 本地存储
        setItem('TOUTIAO_CHANNELS', this.myChannels)
      }
    },
    // 切换频道
    async goChannel (channel, index) {
      // 页面是页面,逻辑是逻辑,作业面上的某个条件判断时,既需要改页面,也需要添加相应的代码逻辑
      if (this.isEditShow) {
        // 如果索引为0, 则为推荐频道不可删除
        if (index === 0) {
          return
        }
        // 在编辑状态下删除频道
        this.myChannelsClone.splice(index, 1)
        // 判断删除元素的索引与当前高亮元素的索引,来确定active值
        if (index <= this.active) {
          // 给updateActive 事件添加新的参数, 来确定是否关闭弹出层
          this.$emit('updateActive', this.active - 1, true)
        }

        // 数据持久化, 判断用户是否登录
        if (this.user.token) {
        // 已登录 - 调接口
          try {
            await delUserChannelAPI(channel.id)
          } catch (error) {
            console.log(error)
            this.$$toast('删除失败')
          }
        } else {
        // 未登录 - 本地存储
          setItem('TOUTIAO_CHANNELS', this.myChannels)
        }
      } else {
        // 在非编辑状态下, 切换频道操作
        this.$emit('updateActive', index)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.channel-edit-container {
  .van-cell__title {
    color: #333;
    font-size: 32px;
    line-height: 58px;
  }
  .edit-btn {
    width: 104px;
    height: 48px;
    font-size: 26px;
    color: #f85959;
    border: 1px solid #f85959;
  }
  :deep(.channel-item){
    width: 160px;
    height: 85px;
    .van-grid-item__content {
      background-color: #f5f5f6;
      white-space: nowrap;
      .text {
        color: #222;
        font-size: 28px;
        margin-top: 0;
      }
      // 高亮频道样式
      .active {
        color: red;
      }
      .van-grid-item__icon-wrapper {
        position: unset;
      }
      .van-icon-close {
        position: absolute;
        right: -10px;
        top: -10px;
        font-size: 30px;
        color: #cacaca;
        z-index: 2;
      }
    }
  }
  .recommend-grid {
    :deep(.van-grid-item__content) {
      flex-direction: row;
      white-space: nowrap;
      .van-icon-plus{
        font-size: 28px;
        margin-right: 6px;
      }

    }
  }
}
</style>
